;
;***************************************************************
;                                                              *
; F I L E   N A M E :    M A C R O Z . M 8 0                   *
;                                                              *
;***************************************************************
;
;***************************************************************
;                                                              *
; THIS IS THE "OLD" MACRO.LIB SUPPLIED WITH "MAC" BY DIGITAL   *
; RESEARCH.  I HAVE MODIFIED IT TO RUN WITH "M80" BY MICROSOFT *
; BY CHANGING SOME OF THE PSUEDO OP'S AND CONVERTED THE 8080   *
; MNEMONICS TO Z-80 MNEMONICS.                                 *
;                                                              *
;           DAVID NIENHISER     NOVEMBER 3, 1980               *
;                                                              *
;***************************************************************

;NOTE: Z80 MODE ENABLED HERE!
.Z80
;
;	SAVE MACRO	SAVE SPECIFIED REGISTERS
;
;	SAVE	R1,R2,R3,R4
;
;		R1-R4 MAY BE BC,DE,HL OR AF  SAVED IN ORDER SPECIFIED
;		IF REGS ARE OMITTED SAVE BC,DE AND HL
;
SAVE	MACRO	R1,R2,R3,R4
	IFNB	<R1&R2&R3&R4>
	IRP	R,<<R1>,<R2>,<R3>,<R4>>
	IFB	<R>
	EXITM
	ENDIF
	PUSH	R
	ENDM
	ELSE
	IRP	REG,<BC,DE,HL>
	PUSH	REG
	ENDM
	ENDIF
	ENDM
;
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	RESTORE MACRO	RESTORE REGISTERS  (INVERSE OF SAVE)
;
;	RESTORE	R1,R2,R3,R4
;
;		R1-R4 MAY BE BC,DE,HL OR AF  RESTORED IN ORDER SPECIFIED
;		IF REGS OMITTED RESTORE HL,DE AND BC
;
RESTORE	MACRO	R1,R2,R3,R4
	IFNB	<R1&R2&R3&R4>
	IRP	R,<<R1>,<R2>,<R3>,<R4>>
	IFB	<R>
	EXITM
	ENDIF
	POP	R
	ENDM
	ELSE
	IRP	REG,<HL,DE,BC>
	POP	REG
	ENDM
	ENDIF
	ENDM
;
;
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	CHARIN MACRO	CONSOLE INPUT TO A
;
;	CHARIN	ADDR
;
CHARIN	MACRO	ADDR
	LD	C,1D
	CALL	5		;;CALL BDOS
	IFNB	<ADDR>
	LD	(ADDR),A
	ENDIF
	ENDM
;
;
;	. . . . . . . . . . . . . . ... ... . .. . . . . . . . .
;
;	CHAROUT MACRO	CONSOLE OUTPUT FROM A
;
;	CHAROUT	ADDR
;
CHAROUT	MACRO	ADDR
	IFNB	<ADDR>
	LD	A,(ADDR)
	ENDIF
	LD	C,2D
	LD	E,A
	CALL	5		;;CALL BDOS
	ENDM
;
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	CHARSTAT MACRO	CHECK CONSOLE STATUS
;
;			RETURN TRUE (FF) IF CHAR READY FALSE (0) IF NOT
;
CHARSTAT MACRO
	LOCAL	ENDSTA
	LD	C,11D
	CALL	5
	OR	A
	JP	Z,ENDSTA
	LD	A,X'FF'
ENDSTA:
	ENDM
;
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	INPUT MACRO	INPUT CHARACTER STRING FROM CONSOLE
;
;	INPUT	ADDR,BUFLEN
;
;		ADDR	START OF TEXT BUFFER
;		BUFLEN	LENGTH OF BUFFER  (DEFAULT IS 127)
;
INPUT	MACRO	ADDR,BUFLEN
	LD	C,10D
	IFNB	<ADDR>
	LD	DE,ADDR
	ENDIF
	IFNB	<BUFLEN>
	LD	A,BUFLEN
	LD	(DE),A
	ELSE
	LD	A,127D
	LD	(DE),A
	ENDIF
	CALL	5		;;BDOS ENTRY
	ENDM
;
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	PRINT MACRO	PRINT A STRING ON CONSOLE
;
;	PRINT				(CARRIAGE RETURN, LINE FEED)
;	PRINT	'LITERAL'
;	PRINT	<'LITERAL',CR,LF,'SECOND LITERAL'>
;
;	PRINT	ADDR,$			(ASCII OUTPUT UNTIL $)
;	PRINT	ADDR,L,H		(HEX OUTPUT L CHARACTERS)
;	PRINT	ADDR,L,A		(ASCII OUTPUT L CHARACTERS)
;
;		LITERALS MUST BE IN SINGLE QUOTES  'LIT'
;		IF LITERAL CONTAINS CONTROL CODES ENTIRE STRING IN <> BRACKETS
;		MACRO ALSO ASSEMBLES
;			CR = CARRIAGE RETURN
;			LF = LINE FEED
;			BEL = BELL CODE
;
;		MACRO ASSUMES ADDR ALREADY LOADED TO HL IF ARGUMENT OMITTED
;
PRINT	MACRO	?STRING,LEN,TC
	LOCAL	@OVER,@MESS,PLOOP,PASTCR,@CRLF
	LOCAL	HLAB
.8080
CR	SET	0DH
LF	SET	0AH
BEL	SET	07H
HLAB	EQU	'H'
.Z80
	IFB	<?STRING&LEN&TC>
	JP	PASTCR
	DSEG
@CRLF:
	DB	CR
	DB	LF
	DB	'$'
	CSEG
PASTCR:	LD	DE,@CRLF
	LD	C,9D
	CALL	5
	ELSE
	IFB	<LEN&TC>
	JP	@OVER
	DSEG
@MESS:
	DB	?STRING
	DB	'$'
	CSEG
@OVER:	LD	DE,@MESS
	LD	C,9D
	CALL	5		;;BDOS ENTRY
	ELSE
	IFB	<TC>
	IFNB	<?STRING>
	LD	DE,?STRING
	ENDIF
	LD	C,9D
	CALL	5		;;BDOS ENTRY
	ELSE
	IFNB	<?STRING>
	LD	HL,?STRING
	ENDIF
	LD	C,LEN
PLOOP:	PUSH	BC
	PUSH	HL
	IF  '&TC' EQ HLAB
	LD	A,(HL)
	HEXOUT			;;CONV TO HEX & OUTPUT
	ELSE
	LD	E,(HL)
	LD	C,2D
	CALL	5
	ENDIF
	POP	HL
	POP	BC
	INC	HL
	DEC	C
	JP	NZ,PLOOP
	ENDIF
	ENDIF
	ENDIF
	ENDM
;
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	HEXOUT MACRO	CONVERT BINARY NO AND OUTPUT TO CONSOLE
;
;	HEXOUT	ADDR
;
;		NUMBER ASSUMED IN A IF NO ARGUMENT
;
HEXOUT	MACRO	ADDR
	LOCAL	OUTCHR,HEXEND
	JR	HEXEND
HEXPRN:	SAVE	AF
	RRCA
	RRCA
	RRCA
	RRCA			;;SHIFT RIGHT 4
	CALL	OUTCHR
	RESTORE	AF
OUTCHR:	AND	X'0F'
	ADD	A,X'90'
	DAA			;;DEC ADJUST
	ADC	A,X'40'
	DAA			;;DEC ADJUST
	LD	E,A
	LD	C,2
	JP	5		;;CALL BDOS
HEXEND:
HEXOUT	MACRO	?ADDR
	IFNB	<?ADDR>
	LD	A,(?ADDR)
	ENDIF
	CALL	HEXPRN
	ENDM
	HEXOUT	ADDR
	ENDM
;
;
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	HEXIN MACRO	CONVERT A NUMBER IN MEMORY FROM HEX TO BINARY
;
;			IF NO ARGUMENT MACRO ASSUMES ADDR OF HEX STRING IN HL
;			ANSWER LEFT IN HL WITH LEAST SIGNIFICANT 8 BITS IN A
;			CARRY SET ON ERROR. CONVERSION STOPS WHEN ZERO IS
;			FOUND IN HEX STRING.
;
HEXIN	MACRO	ADDR
	LOCAL	IN1,IN2,OVRHEX
	JR	OVRHEX
@HEXIN:	LD	HL,0D
IN1:	LD	A,(DE)
	OR	A		;;CHECK FOR END OF BUFFER
	RET	Z
	SUB	'0'		;;CHECK < 0 AND CONVERT TO HEX
	RET	C
	ADD	A,'0'-'G'		;;CHECK > F
	RET	C
	ADD	A,6
	JP	P,IN2
	ADD	A,7
	RET	C
IN2:	ADD	A,10
	OR	A		;;CLEAR CARRY
	LD	C,A
	LD	B,0		;;ZERO TO B
	ADD	HL,HL
	ADD	HL,HL
	ADD	HL,HL
	ADD	HL,HL		;;SHIFT LEFT 4
	ADD	HL,BC
	INC	DE		;;INCR BUFFER POINTER
	JR	IN1		;;RETURN FOR MORE INPUT
OVRHEX:
HEXIN	MACRO	?ADDR
	IFNB	<?ADDR>
	LD	DE,?ADDR		;;LOAD BUFFER ADDR
	ELSE
	EX	DE,HL
	ENDIF
	CALL	@HEXIN
	LD	A,L		;;LEAST SIGNIFICANT 8 BITS TO A
	ENDM
	HEXIN	ADDR
	ENDM
;
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	DECOUT MACRO	CONVERT A POSITIVE INTEGER TO DECIMAL AND OUTPUT 
;			TO THE CONSOLE.
;
;	DECOUT	ADDR
;
;		IF ADDR OMITTED, NUMBER ASSUMED TO BE IN HL, ELSE LOADED TO HL
;		LEADING ZEROS SUPRESSED. MAXIMUM NUMBER 65,767
;
DECOUT	MACRO	ADDR
	LOCAL	ENDDEC,DX
	JR	ENDDEC
@DECOUT:SAVE			;;PUSH STACK
	LD	BC,-10		;;RADIX FOR CONVERSION
	LD	DE,-1		;;THIS BECOMES NO DIVIDED BY RADIX
DX:	ADD	HL,BC		;;SUBTRACT 10
	INC	DE
	JP	C,DX
	LD	BC,10
	ADD	HL,BC		;;ADD RADIX BACK IN ONCE
	EX	DE,HL
	LD	A,H
	OR	L		;;TEST FOR ZERO
	CALL	NZ,@DECOUT	;;RECURSIVE CALL
	LD	A,E
	ADD	A,'0'		;;CONVERT FROM BCD TO HEX
	LD	E,A		;;TO E FOR OUTPUT
	CHAROUT			;;CONSOLE OUTPUT
	RESTORE			;;POP STACK
	RET
ENDDEC:
DECOUT	MACRO	?ADDR
	IFNB	<?ADDR>
	LD	HL,(?ADDR)
	ENDIF
	CALL	@DECOUT		;;CALL THE SUBROUTINE
	ENDM
	DECOUT	ADDR
	ENDM
;
;
;
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	DECIN MACRO	CONVERT A NUMBER IN MEMORY FROM ASCII TO BINARY
;
;	DECIN	ADDR
;
;		ADDR POINTS TO MEMORY LOCATION OF START OF NO, IF
;		ARG OMITTED POINTER ASSUMED LOADED TO HL
;		MACRO RETURNS WITH CARRY SET IF ALPHABETIC CHAR FOUND
;		CONVERSION STOPS WHEN CHAR LESS THAN ZERO IS FOUND.
;		BINARY NUMBER IS LEFT IN HL, MAXIMUM 65,767
;		LEAST SIGNIFICANT 8 BITS OF NUMBER IN A.
;
DECIN	MACRO	ADDR
	LOCAL	DLOOP,@OVER1
	JR	@OVER1
@DECIN:	LD	DE,0		;;ZERO DE
	EX	DE,HL
DLOOP:	LD	A,(DE)
	SUB	'O'
	AND	A
	RET	M
	CP	10D
	CCF
	RET	C
	INC	DE		;;INCR ADDR POINTER
	ADD	HL,HL		;;SHIFT LEFT 1
	PUSH	HL		;;SAVE RESULT
	ADD	HL,HL
	ADD	HL,HL
	POP	BC		;;NO * 2 TO B
	ADD	HL,BC
	LD	C,A		;;ADD PRODUCT TO DIGIT
	LD	B,0
	ADD	HL,BC
	JP	DLOOP		;;BACK FOR ANOTHER DIGIT
@OVER1:
DECIN	MACRO	?ADDR
	IFNB	<?ADDR>
	LD	HL,?ADDR
	ENDIF
	CALL	@DECIN		;;CALL THE SUBROUTINE
	LD	A,L		;;LEAST SIGNIFICANT HALF OF NO TO A
	ENDM
	DECIN	ADDR
	ENDM
;
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	MOVE MACRO	MOVE A BLOCK FROM SOURCE TO DEST
;
;	MOVE	SOURCE,DEST,COUNT
;
;		SOURCE TO HL	MACRO ASSUMES REGISTERS ALREADY
;		DEST TO DE	LOADED IF ARG OMITTED
;		COUNT TO BC
;
MOVE	MACRO	SOURCE,DEST,COUNT
	LOCAL	OVRMOV
	JR	OVRMOV
@MOVE:	LD	A,B
	OR	C
	RET	Z
	LD	A,(HL)
	LD	(DE),A
	INC	HL
	INC	DE
	DEC	BC
	JR	@MOVE		;;BACK TO MOVE LOOP
OVRMOV:
MOVE	MACRO	SRC,?D,?C
	IFNB	<SRC>
	LD	HL,SRC
	ENDIF
	IFNB	<?D>
	LD	DE,?D
	ENDIF
	IFNB	<?C>
	LD	BC,?C
	ENDIF
	CALL	@MOVE		;;CALL THE MOVE SUBROUTINE
	ENDM
	MOVE	SOURCE,DEST,COUNT
	ENDM
;
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	FILL MACRO - FILL A BLOCK OF MEMORY WITH A CONSTANT
;
;	FILL	START,STOP,CONSTANT
;
;		CONSTANT OMITTED, FILL WITH 0
;		END OMITTED, FILL ONE BYTE
;
FILL	MACRO	START,STOP,CONST
	LOCAL	@FILL,BLKLEN
.8080
BLKLEN	SET	STOP-START+1
.Z80
	LD	HL,START		;;LOAD START ADDR
	IFNB	<STOP>
	IF	BLKLEN GT 255
	LD	BC,BLKLEN	;;LOAD BLOCK LENGTH
	ELSE
	LD	C,BLKLEN AND X'FF'
	ENDIF
	IFNB	<CONST>
	LD	E,CONST		;;LOAD CONST IF NOT NULL
	ELSE
	LD	E,0
	ENDIF
@FILL:	LD	(HL),E		;;STORE A BYTE
	INC	HL		;;INCR MEMORY POINTER
	IF	BLKLEN GT 255
	DEC	BC		;;DECR COUNT
	LD	A,C		;;TEST LIMIT
	OR	B
	JR	NZ,@FILL		;;CONTINUE
	ELSE
	DEC	C
	JR	NZ,@FILL
	ENDIF
	ELSE
	IFB	<CONST>
	LD	(HL),0
	ELSE
	LD	(HL),CONST
	ENDIF
	ENDIF
	ENDM
;
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;
;	MATCH MACRO	COMPARE 2 STRINGS OF SAME LENGTH SET CARRY IF EQUAL
;
;	MATCH	STR1,'LITERAL STRING'
;	MATCH	STR1,STR2,LENGTH
;	MATCH
;
;		DE POINTS TO STR1	MACRO WILL LOAD REG IF ARG
;		HL POINTS TO STR2	PRESENT
;		C CONTAINS LENGTH
;
;		SUBTRACT STR2 FROM STR1 AND SET FLAGS, ZERO INDICATES MATCH.
;		NORMALLY THE SECOND ARG IS A LITERAL STRING AND THE LENGTH
;		IS OMITTED. IF THE LEN ARG IS PRESENT THE SECOND STRING
;		ARG IS ASSUMED TO BE A MEMORY ADDR. IF ALL ARGUMENTS OMITTED
;		REGISTERS ASSUMED ALREADY LOADED.
;
;    NOTE:  I HAD BETTER LUCK WITH THIS ONE TESTING THE ZERO
;           FLAG INSTEAD OF THE CARRY FLAG.  D. NIENHISER
;
MATCH	MACRO	STR1,STR2,LEN
	LOCAL	OVRMAT,M1
	JR	OVRMAT
@MATCH:	INC	C		;;PRE INCREMENT COUNT (IT MIGHT BE ZERO)
M1:	DEC	C		;;DECR LENGTH COUNT
	RET	Z
	LD	A,(DE)
	SUB	(HL)		;;COMPARE WITH OTHER
	RET	NZ
	INC	HL
	INC	DE		;;INCR STRING POINTERS
	JR	M1		;;TRY SOME MORE
OVRMAT:
MATCH	MACRO	?STR1,?STR2,?LEN
	LOCAL	LITSTR,ENDLIT
	IFB	<?STR1&?STR2&LEN>
	CALL	@MATCH
	ELSE
	IFNB	<?STR1>
	LD	DE,?STR1		;;LOAD STRING1 POINTER
	ENDIF
	IFB	<?LEN>
	LD	C,ENDLIT-LITSTR	;;LENGTH OF LITERAL STRING
	LD	HL,LITSTR	;;POINTER TO LITERAL
	CALL	@MATCH
	JR	ENDLIT
LITSTR:	DB	?STR2		;;LITERAL STRING
ENDLIT:				;;END OF STRING
	ELSE
	IFNB	<?STR2>
	LD	HL,?STR2		;;LOAD POINTER TO STRING2
	ENDIF
	LD	C,?LEN		;;LOAD STRING LENGTH
	CALL	@MATCH		;;CALL MATCH SUBROUTINE
	ENDIF
	ENDIF
	ENDM
	MATCH	STR1,STR2,LEN
	ENDM
;
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	INSTR MACRO	SEARCH STRING FOR SUBSTRING AND SET CARRY IF FOUND
;
;	INSTR	STRING,LENGTH,SUBSTR
;
;		HL	POINTS TO STRING
;		DE	POINTS TO SUBSTRING
;		B	CONTAINS STRING LENGTH
;		C	CONTAINS SUBSTRING LENGTH
;
;		MACRO RETURNS POINTER TO END OF SUBSTRING IN HL
;
;             N O T E:  THE MATCH MACRO MUST BE INVOKED BEFORE
;                       THIS MACRO CAN BE USED.
;
INSTR	MACRO	STRING,LENGTH,SUBST
	LOCAL	OVRINS,S1,SSX
	JR	OVRINS
@INSTR:	LD	A,B		;;STRING LENGTH
	SUB	C		;;SUBTRACT SUBSTR LENGTH
	CCF			;;COMP CARRY
	RET	NC
	LD	B,A		;;NEW STRING LIMIT TO B
S1:	SAVE
	MATCH
	RESTORE
	JR	Z,SSX		;;MATCH IF ZERO ON RET
	AND	A		;;RESET CARRY
	DEC	B		;;BYTES LEFT
	RET	M
	INC	HL		;;INCR STRING POINTER
	JR	S1		;;TRY AGAIN
SSX:	LD	B,0		;;SET D TO 0
	ADD	HL,BC
	SCF			;;SET CARRY
	RET
OVRINS:
INSTR	MACRO	?STR,?LEN,?SUBST
	LOCAL	LITSTR,ENDLIT
	IFNB	<?STR>
	LD	HL,?STR
	ENDIF
	LD	B,?LEN
	LD	C,ENDLIT-LITSTR
	LD	DE,LITSTR
	CALL	@INSTR
	JR	ENDLIT
LITSTR:	DB	?SUBST
ENDLIT:
	ENDM
	INSTR	STRING,LENGTH,SUBST
	ENDM
;
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	SCAN MACRO	SCAN A STRING UNTIL A CHAR IS FOUND, SKIP BLANKS
;			AND CONTROL CHARACTERS
;
;			CARRY SET IF NUMERIC, CARRY OFF IF ALPHABETIC
;
;
SCAN	MACRO	ADDR
	LOCAL	OVRSCA
	JR	OVRSCA
@SCAN:	LD	A,(HL)
	CP	21H		;;SPACE OR LESS?
	RET	P
	INC	HL		;;INCR POINTER
	JR	@SCAN		;;KEEP SEARCHING
OVRSCA:
SCAN	MACRO	?ADDR
	IFNB	<?ADDR>
	LD	HL,?ADDR
	ENDIF
	CALL	@SCAN		;;CALL SUBROUTINE
	CP	3AH		;;NUMBER OR ALPHA
	ENDM
	SCAN	ADDR
	ENDM
;
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	DISKIO MACRO	EXECUTE BDOS DISK ACCESS PRIMITIVES
;
;	NOTE: CP/M 2.2 FUNCTIONS ADDED!  D.NIENHISER 11/80
;
;	DISKIO	FUNCTION,PARAMETER
;
;		NO	FUNCTION	ENTRY PARAM
;
;		12	LIFTHEAD
;		13	INITIAL
;		14	LOGIN		DISK NO 0 - 1
;		15	OPEN		FCB
;		16	CLOSE		FCB
;		17	SEARCH		FCB
;		18	SERNXT		FCB
;		19	DELETE		FCB
;		20	READ		FCB
;		21	WRITE		FCB
;		22	MAKE		FCB
;		23	RENAME		FCB
;		24	?LOGIN
;		25	?DRIVE
;		26	SETDMA		BUFFER
;		27	?ALLOC
;		28	WRPDSK
;		29	GETROV
;		30	SETFAT		FCB
;		31	GETDAT
;		32	GTSTUC
;		33	READRA		FCB
;		34	WRITRA		FCB
;		35	COMFSZ		FCB
;		36	SETRRC		FCB
;		37	RSTDRV
;		40	RANWR		FCB
;		SEE CP/M INTERFACE GUIDE FOR DETAILED INFORMATION ON THE
;		DISK ACCESS PRIMITIVES
;
;	DISKIO	READ,FCB	(TYPICAL MACRO CALL)
;
DISKIO	MACRO	FUNCTI,PARAME
.8080
LIFTHEAD	SET	12
INITIAL		SET	13
LOGIN		SET	14
OPEN		SET	15
CLOSE		SET	16
SEARCH		SET	17
SERNXT		SET	18
DELETE		SET	19
READ		SET	20
WRITE		SET	21
MAKE		SET	22
RENAME		SET	23
?LOGIN		SET	24
?DRIVE		SET	25
SETDMA		SET	26
?ALLOC		SET	27
WRPDSK		SET	28
GETROV		SET	29
SETFAT		SET	30
GETDAT		SET	31
GTSTUC		SET	32
READRA		SET	33
WRITRA		SET	34
COMFSZ		SET	35
SETRRC		SET	36
RSTDRV		SET	37
RANWR		SET	40
;
?C	SET	FUNCTI
.Z80
	IFNB	<PARAME>
	LD	DE,PARAME
	ENDIF
	LD	BC,?C
	CALL	5		;;BDOS ENTRY
	ENDM
;
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	CALLBIOS MACRO	CALL BIOS ROUTINES DIRECTLY
;
;	NOTE:	CP/M 2.2 VECTORS HAVE BEEN ADDED
;		D. NIENHISER    11/80
;
;	CALLBIOS	FUNCTION,PARAM
;
CALLBIOS	MACRO	FUNCT,PARAM
	LOCAL	@CALL
;
.8080
DCOLD	SET	00H
DWBOOT	SET	03H
DSTAT	SET	06H
DCONIN	SET	09H
DCONOUT	SET	0CH		;;CHAR IN C
DLIST	SET	0FH		;;CHAR IN C
DPUNCH	SET	12H
DREADER	SET	15H
DHOME	SET	18H
DSELDSK	SET	1BH
DSETTRK	SET	1EH
DSETSEC	SET	21H		;;SECTOR NO IN C
DSETDMA	SET	24H		;;DMA ADDR IN BC
DREAD	SET	27H
DWRITE	SET	2AH
LISTST	SET	2DH
SECTRN	SET	30H
;
?F	SET	FUNCT
.Z80
	IFNB	<PARAM>
	LD	BC,PARAM
	ENDIF
	LD	HL,(1)
	LD	L,?F AND X'FF'
	LD	(@CALL+1),HL
@CALL:	CALL	0
	ENDM
;
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	DLOAD MACRO	DOUBLE PRECISION INDEXED LOAD HL
;
;		LOAD (ADDR + INDX) TO HL
;
DLOAD	MACRO	ADDR,INDX
	IFB	<INDX>
	LD	HL,(ADDR)
	ELSE
	LD	HL,(INDX)
	LD	DE,ADDR
	ADD	HL,DE
	LD	E,(HL)
	INC	HL
	LD	D,(HL)
	EX	DE,HL
	ENDIF
	ENDM
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	CPHL MACRO	SUBTRACT DE FROM HL AND SET FLAGS
;
CPHL	MACRO
	LOCAL	@END
	LD	A,H
	CP	D		;;COMPARE HIGH BYTES
	JR	NZ,@END
	LD	A,L
	CP	E		;;COMPARE LOW BYTES
@END:
	ENDM
;
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	DJZ MACRO	DOUBLE PRECISION TEST HL AND JUMP ON ZERO
;
DJZ	MACRO	ADDR
	LD	A,H
	OR	L
	JP	Z,ADDR
	ENDM
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	DSTORE MACRO	DOUBLE PRECISION INDEXED STORE HL
;
;		STORE (HL) IN (ADDR + INDX)
;
DSTORE	MACRO	ADDR,INDX
	IFB	<INDX>
	LD	(ADDR),HL
	ELSE
	SAVE	HL
	LD	HL,(INDX)
	EX	DE,HL
	LD	HL,ADDR
	ADD	HL,DE
	RESTORE	DE
	LD	(HL),E
	INC	HL
	LD	(HL),D
	ENDIF
	ENDM
;
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	INDEX MACRO	INDEX AN ADDRESS POINTER BY A CONSTANT
;
;	INDEX	POINTER,INCR
;
INDEX	MACRO	POINTER,INCR
	LD	HL,(POINTER)
	LD	DE,INCR
	ADD	HL,DE
	LD	(POINTER),HL
	ENDM
;
;	. . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	FILFCB	MACRO	FILL IN THE ID FIELDS OF FCB
;
;	FILFCB	FCB,IDSTRING
;
;		IDSTRING CONTAINS FILE NAME AND TYPE  (FILNAM.TYP)
;		CARRY SET IF ERROR  (NAME TOO LONG)
;
FILFCB	MACRO	FCB,IDSTRI
	LOCAL	OVRFIL,F1,F2,F3,F4,F5,F6
	JR	OVRFIL
@FLFCB:	LD	(HL),0
	INC	HL
	PUSH	HL
	LD	C,11		;;SIZE OF ID FIELD
	LD	A,' '		;;SPACE TO A
F1:	LD	(HL),A
	INC	HL
	DEC	C
	JR	NZ,F1
	POP	HL		;;RESTORE NAME POINTER
	LD	C,8		;;MAXIMUM SIZE OF NAME
F2:	LD	A,(DE)
	CP	' '		;;LEADING SPACES?
	JR	NZ,F3
	INC	DE
	JR	F2
F3:	LD	A,(DE)
	CP	0		;;ZERO END OF FIELD
	RET	Z
	CP	' '		;;SPACE END OF FIELD
	RET	Z
	CP	'.'		;;PERIOD TYPE SEPARATOR
	JR	Z,F4
	LD	(HL),A
	INC	HL
	INC	DE
	DEC	C
	JP	P,F3
	SCF			;;SET CARRY NAME TOO LARGE
	RET
F4:	INC	DE		;;SKIP THE PERIOD
	LD	A,C
	OR	A
	JR	Z,F6		;;TEST C FOR ZERO
F5:	INC	HL
	DEC	C
	JR	NZ,F5
F6:	LD	C,3		;;SIZE OF TYPE FIELD
F7:	LD	A,(DE)
	CP	0		;;ZERO?
	RET	Z
	CP	' '		;;SPACE?
	RET	Z
	LD	(HL),A
	INC	HL
	INC	DE
	DEC	C
	JR	NZ,F7
	RET
OVRFIL:
FILFCB	MACRO	?FCB,?ID
	IFNB	<?ID>
	LD	DE,?ID
	ENDIF
	IFNB	<?FCB>
	LD	HL,?FCB
	ENDIF
	CALL	@FLFCB
	EX	DE,HL
	ENDM
	FILFCB	FCB,IDSTRI
	ENDM
;
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	SETTRK MACRO	SET AND TEST TRACK NUMBER
;
;			CARRY SET IF > 76
;
SETTRK	MACRO	TRKNO
	LOCAL	ENDTRK
	IFNB	<TRKNO>
	LD	A,TRKNO
	ENDIF
	CP	77
	CCF
	JR	C,ENDTRK
	LD	C,A		;;TRACK NO TO C
	CALLBIOS DSETTRK
ENDTRK:
	ENDM
;
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	SETSEC MACRO	SET AND TEST SECTOR NUMBER
;
;		RETURN WITH CARRY SET < 1 OR > 26
;
SETSEC	MACRO	SECNO
	LOCAL	ENDSEC
	IFNB	<SECNO>
	LD	A,SECNO
	ENDIF
	OR	A		;CHECK ZERO
	SCF
	JR	Z,ENDSEC
	CP	27		;CHECK > 26
	CCF
	JP	C,ENDSEC
	LD	C,A		;MOVE TO C
	CALLBIOS DSETSEC
ENDSEC:
	ENDM
;	. . . . . . . . . . . . . . . . . . . . . . . . . . . .
;
;	HALF MACRO	DIVIDES A 16 BIT NUMBER BY 2
;
HALF	MACRO	I
	LOCAL	OVER
	JR	OVER
@HALF:	XOR	A		;;CLEAR CARRY
	LD	A,H
	RRA			;;SHIFT UPPER HALF
	LD	H,A
	LD	A,L
	RRA			;;SHIFT LOWER HALF
	LD	L,A
	RET
OVER:
HALF	MACRO	?I
	IFNB	<?I>
	LD	HL,(?I)
	ENDIF
	CALL	@HALF
	ENDM
	HALF	I
	ENDM
